#include "inc/hw_memmap.h"
#include "wdt_a.h"
#include "ucs.h"
#include "gpio.h"
#include "pmm.h"

#include "h1010.h"
#include "DataType.h"
#include "SI.h"
#include "SOSZ.h"
#include "Serial.h"
#include "main.h"
#include "ConfigMem.h"
#include "I2C_IO_Driver.h"
#include "LED.h"
#include "Fault.h"
#include "Relay.h"
#include "Button.h"
#include "Buzzer.h"
#include "GA.h"
#include "FWS.h"
#include "Resource.h"

#define BUFF_SIZE 5300
static unsigned char buff[BUFF_SIZE];
const struct configMemRAM_t * pConfigMemRAM = (struct configMemRAM_t *)&buff[0];
//---------------------------------------------------------------------------
//  GLOBAL INITIALIZATIONS
//---------------------------------------------------------------------------
//-------------------------------------------------
// Define instances of Configuration structures
//-------------------------------------------------
//struct SysConfigAddress stSysConfigAddress;
//struct SysConfig stSysConfig;
//struct SI stSI[TOTAL_SI];
//SO stSZ[TOTAL_SZ];
//SO stSO[TOTAL_SO];
//SO stREL[TOTAL_REL];
//GA stGA;
//xAbort stAbort;
//struct HWTests stHWTests;
//FWS stFWS[TOTAL_FWS_SECTORS];
//struct REVNO stREVNO;
//FWS_Ext02 stFWS02[TOTAL_FWS_SECTORS];
//DSP_Message stMESSAGE[TOTAL_MESSAGE];
//extern unsigned char * pImage;
//extern unsigned char Image[5029];

#define DEMO_SERIAL 0
#define DEMO_BLINK_RATES 0
#define DEMO_SI	1
#define DEMO_SO 0
#define DEMO_CHRISTMAS_TREE 0


RTN_TYPE isValidConfigSaved(unsigned char onInit)
{
//	unsigned int size;
	unsigned char revision=0;
//    size = sizeof(struct REVNO) - 2;
    configMem_copyToRAM((unsigned char*)&revision, 1, 1123);
    if (onInit)
    {
		if (revision>0x90 || revision < 0x70)
		{
			return RTN_ERROR_GEN;
		}
    }
    else
    {
    	if (revision<0x90 || revision > 0x70 || revision == 0)
		{
			return RTN_SUCCESS;
		}
    	else
    	{
    		return RTN_ERROR_GEN;
    	}

    }
    return RTN_SUCCESS;
}

unsigned int status = STATUS_SUCCESS ;
void init (void)
{

	//Stop WDT
    WDT_A_hold(WDT_A_BASE);

    status = PMM_setVCore(PMM_BASE, PMMCOREV_3);

    //Set DCO FLL reference = REFO
	UCS_clockSignalInit(UCS_BASE, UCS_FLLREF, UCS_REFOCLK_SELECT, UCS_CLOCK_DIVIDER_1);

	//Set ACLK = REFO
	UCS_clockSignalInit(UCS_BASE, UCS_ACLK, UCS_REFOCLK_SELECT, UCS_CLOCK_DIVIDER_1);

	SFRIE1 &= ~OFIE;                        //disable oscillator fault before configuring FLL
	                                            // because of DCOFFG

	//! \param baseAddress is the base address of the UCS module.
	//! \param fsystem is the target frequency for MCLK in kHz
	//! \param ratio is the ratio x/y, where x = fsystem and
	//!         y = FLL reference frequency.

#if TIMER_1MHz_div1
	UCS_initFLLSettle(UCS_BASE, 1048, 32); //~ 32*32768 = 1048576
#elif TIMER_8MHz_div8
	UCS_initFLLSettle(UCS_BASE, 8384, 256); //~ 256*32768 = 8388608
#elif TIMER_16Mhz_div8
	UCS_initFLLSettle(UCS_BASE, 15991, 488); //~ 512*32768 = 16777216
#elif TIMER_16Mhz_div16
	UCS_initFLLSettle(UCS_BASE, 15991, 488); //~ 512*32768 = 16777216
#endif
//

//	UCS_initFLLSettle(UCS_BASE, 16768, 512); //~ 512*32768 = 16777216
//	UCS_initFLLSettle(UCS_BASE, 25001, 763); //~ 763*32768 = 25001984
//	UCS_initFLLSettle(UCS_BASE, 31982, 976); //~ 976*32768 = 31981568
//	P11DIR |= BIT2;
//	P11SEL |= BIT2;

//	SFRIE1 |= OFIE | NMIIE | ACCVIE | VMAIE;// | WDTIE;

}
void test_cfgMem(void)
{
	int i; //unsigned int size;
	unsigned char *p;
//	configMem_updateFLASH((unsigned char*)&buff[8], sizeof(struct configMemRAM_t));
	p = &buff[0];
	for (i=0; i<BUFF_SIZE;i++) 						{*p = 0x00; p++;}
	p = (unsigned char *)pConfigMemRAM;
	for (i=0; i<sizeof(struct configMemRAM_t);i++) 	{*p = 0x55; p++;}

//	configMem_updateFLASH((unsigned char*)&buff[8], sizeof(struct configMemRAM_t));
	p = &buff[0];
	for (i=0; i<BUFF_SIZE;i++) {*p = 0x55; p++;}
}
void memfill(BYTE * p, BYTE value, unsigned int bytes)
{
	BYTE * pc = (BYTE *) p;
	while (bytes--)
	{
		*pc++ = value;
	}
}
void init_system(void)
{
	_disable_interrupt();
	SO_out_init();

	Buzzer_init();
	BTN_init();

    SI_init();
	SOSZ_init();
	Fault_init();
	Relay_init();
	GA_init();
	FWS_init();

	test_testPin_init();
	test_testPin2_init();
	test_testPin3_init();
	test_testPin4_init();
	testPinPort8_init(GPIO_ALL);
	test_testPin_On();
	test_testPin_Off();
	Test_Serial_init();
//    test_so_2xIssue();
//	test_so_2xIssueIsolated();

//	test_harness(pConfigMemRAM);

	__bis_SR_register(GIE);
	I2CioDriver_init();
	LED_init();
	SI_enable25msISR();

	//Watchdog mode -> reset after expired time; WDT is clocked by ACLK
	//Set Watchdog Timer timeout 1s - SET BREAKPOINT HERE
	WDT_A_watchdogTimerInit(WDT_A_BASE,
		WDT_A_CLOCKSOURCE_ACLK,
//		WDT_A_CLOCKDIVIDER_64); // fail
//		WDT_A_CLOCKDIVIDER_512);// fail
//		WDT_A_CLOCKDIVIDER_8192);
		WDT_A_CLOCKDIVIDER_32K);
	WDT_A_start(WDT_A_BASE);
}

int main (void)
{
	_disable_interrupt();

	init();

 //   init_system();
#if DEMO_CHRISTMAS_TREE
	Test_christmasTree();
//	I2CioDriver_test();
#endif

#if DEMO_SI
	memfill(&buff[0],0,sizeof(buff));
//    pConfigMemRAM=(struct configMemRAM_t *)&buff[0];
    __delay_cycles(100);

    Serial_init((unsigned char *)pConfigMemRAM, BUFF_SIZE);


//    test_cfgMem();
//    int i; unsigned int size; unsigned char *p = (unsigned char *)configMemRAM;

//    __delay_cycles(100);

//    SOSZ_test_init();
    loadInhibitedSettings(pConfigMemRAM);
//    configMem_init();
//    SO_test_driver();
    if (isValidConfigSaved(1) == RTN_SUCCESS)
    {
    	SI_init();
		SOSZ_init();
		Test_Serial_init();
    	if (Serial_transferFlashImageToRAM() != RTN_SUCCESS)
    	{
    		__no_operation();
    	}
//    	SI_test_SH_centCfg(SI_testCfg_DontUse);
    }
    else
    {
		SI_init();
		SOSZ_init();
    	if (loadInhibitedSettings(pConfigMemRAM) != RTN_SUCCESS)
		{
			__no_operation();
		}
		test_loadTestConfig(pConfigMemRAM, SI_2);
///		Test_testHarness();
//    	configMem_setRevision(0x83);
    	configMem_setRevision(0x0);

    }

//    test_loadTestConfig(pConfigMemRAM);
//    configMem_updateFLASH(&buff[0], 5029);

    // Turn LD1 off -- set to output and drive low
    P7DIR |= BIT0;
    P7OUT &= ~BIT0;

    __delay_cycles(100);

    init_system();
//    WDTCTL = 0;
//    while(1);


	Test_Serial_sendCmdAndByte(DebugCmd_init,0x55);

	Test_Serial_sendCmdAndByte(DebugCmd_letterH, ascii_letter_lower_i);
	unsigned char string [] = {"\nPropak MCU Cmd Line:\0\n"};
	Test_Serial_sendCmdAndData(DebugCmd_init, string, sizeof(string));

	unsigned char serialActive = 0;
#if !TARGET_SPX_1_EXP_0
	P11DIR |= BIT2;
	P11SEL |= BIT2;
#endif
    while(1)
    {
  //  	_disable_interrupt();
    		serialActive = Serial_serialOperation;
  //  	__bis_SR_register(GIE);

    	if (serialActive)
    	{
    		Serial_thread();
    	}
    	else
    	{
//    		SI_atomicTimer();
//    		_disable_interrupt();
   		test_testPin_toggle();
#if 1
    		BTN_btnEvent_process();
#endif
#if 1
			SI_thread(0, SI_runMode_norm, SI_runMode_norm);
#endif
///			__bis_SR_register(GIE);
#if 1
			Fault_thread();
			LED_thread();
#endif

//			Test_Serial_sendCmdAndByte(DebugCmd_letterH, ascii_letter_lower_i);
//			Test_Serial_sendCmdAndData(DebugCmd_init, string, sizeof(string));
    	}
//    	test_testPin_Off();
///    	__bis_SR_register(GIE);
    	__no_operation();
    }
#endif
#if DEMO_BLINK_RATES
    I2CioDriver_init();
    LED_init();
    __bis_SR_register(GIE);
    while(1)
    {
    	LED_thread_test();
 //   	__bis_SR_register(LPM3_bits + GIE);
    }
#endif

//    I2CioDriver_test();



//    pImage = &Image[7];

//    LED_init(SI_1_Fault_LED_p, SI_1_FAULT_PORT, SI_1_FAULT_PIN);
//    LED_init(SI_1_Alarm_LED_p, SI_1_ALARM_PORT, SI_1_ALARM_PIN);
//    LED_init(SI_2_Fault_LED_p, SI_2_FAULT_PORT, SI_2_FAULT_PIN);
//    LED_init(SI_2_Alarm_LED_p, SI_2_ALARM_PORT, SI_2_ALARM_PIN);

//    adc12_init();

 //   slaveI2C_setup();


#if 0
    if (configMem_getRevision(0) > 0)
   {
    	__no_operation();
   	loadImage(); // transfer from Flash to RAM ????

    }
    else
    {
    	__no_operation();
    	configMem_init();
//    	disableSystem();
    }
    configMem_init();

    while(1)
    {
    	Serial_thread();
//#if !TS
    	__bis_SR_register(GIE);
    	__no_operation();
 //   	__bis_SR_register(LPM0_bits + GIE);
//		__no_operation();
//#endif
//#if TS
//		USCI_I2C_slaveTx_ISR(USCI_BASE);
//#endif
    }
#endif
}

void unusedISRspiderWeb(unsigned char vectorID)
{
	if (vectorID > 40) {
		__no_operation();
	}
	while(1)
	{
		testPinPort8_on(TEST_SPIDER_WEB);
		__delay_cycles(50);
		testPinPort8_off(TEST_SPIDER_WEB);
	}
}
#pragma vector = RTC_VECTOR
__interrupt void vector41 (void)
{
	unusedISRspiderWeb(41);
}
#pragma vector = PORT2_VECTOR
__interrupt void vector42 (void)
{
	unusedISRspiderWeb(42);
}
#pragma vector = USCI_B3_VECTOR
__interrupt void vector43 (void)
{
	unusedISRspiderWeb(43);
}
#pragma vector = USCI_A3_VECTOR
__interrupt void vector44 (void)
{
	unusedISRspiderWeb(44);
}
/*#pragma vector = USCI_B1_VECTOR
__interrupt void vector45 (void)
{
	unusedISRspiderWeb();
}*/
/*#pragma vector = USCI_A1_VECTOR
__interrupt void vector46 (void)
{
	unusedISRspiderWeb(46);
}*/
#pragma vector = PORT1_VECTOR
__interrupt void vector47 (void)
{
	unusedISRspiderWeb(47);
}
#pragma vector = TIMER1_A1_VECTOR
__interrupt void vector48 (void)
{
	unusedISRspiderWeb(48);
}
/*#pragma vector = TIMER1_A0_VECTOR
__interrupt void vector49 (void)
{
	unusedISRspiderWeb();
}*/
#pragma vector = DMA_VECTOR
__interrupt void vector50 (void)
{
	unusedISRspiderWeb(50);
}
#pragma vector = USCI_B2_VECTOR
__interrupt void vector51 (void)
{
	unusedISRspiderWeb(51);
}
#pragma vector = USCI_A2_VECTOR
__interrupt void vector52 (void)
{
	unusedISRspiderWeb(52);
}
#pragma vector = TIMER0_A1_VECTOR
__interrupt void vector53 (void)
{
	unusedISRspiderWeb(53);
}
#pragma vector = TIMER0_A0_VECTOR
__interrupt void vector54 (void)
{
	unusedISRspiderWeb(54);
}
/*#pragma vector = ADC12_VECTOR
__interrupt void vector55 (void)
{
	unusedISRspiderWeb();
}*/
#pragma vector = USCI_B0_VECTOR
__interrupt void vector56 (void)
{
	unusedISRspiderWeb(56);
}
/*#pragma vector = USCI_A0_VECTOR
__interrupt void vector57 (void)
{
	unusedISRspiderWeb();
}*/
#pragma vector = WDT_VECTOR
__interrupt void vector58 (void)
{
	unusedISRspiderWeb(58);
}
#pragma vector = TIMER0_B1_VECTOR
__interrupt void vector59 (void)
{
	unusedISRspiderWeb(59);
}
#pragma vector = TIMER0_B0_VECTOR
__interrupt void vector60 (void)
{
	unusedISRspiderWeb(60);
}
#pragma vector = UNMI_VECTOR
__interrupt void vector61 (void)
{
	if ((SFRIFG1 & OFIFG) || (UCSCTL7))
	{
		while (SFRIFG1 & OFIFG) {                               // check OFIFG fault flag
			UCSCTL7 &= ~(DCOFFG+XT1LFOFFG+XT1HFOFFG+XT2OFFG);     // Clear OSC flaut Flags
			SFRIFG1 &= ~OFIFG;                                    // Clear OFIFG fault flag
		  }
	}
	else 
	{
		unusedISRspiderWeb(61);
	}
	SFRIFG1 = 0;
}
#pragma vector = SYSNMI_VECTOR
__interrupt void vector62 (void)
{
	unusedISRspiderWeb(62);
}
/*#pragma vector = RESET_VECTOR
__interrupt void vector63 (void)
{
	unusedISRspiderWeb();
}*/


